/*
 *  Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 *  WSO2 Inc. licenses this file to you under the Apache License,
 *  Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package luca.sample.rbac;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.balana.attr.AttributeValue;
import org.wso2.balana.attr.BagAttribute;
import org.wso2.balana.attr.StringAttribute;

import org.wso2.balana.cond.EvaluationResult;
import org.wso2.balana.ctx.EvaluationCtx;
import org.wso2.balana.finder.AttributeFinderModule;
import org.wso2.balana.finder.impl.FileBasedPolicyFinderModule;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import luca.data.AttributeQuery;
import luca.data.XmlDataHandler;

/**
 * Sample attribute finder module. Actually this must be the point that calls to
 * K-Market user store and retrieve the customer attributes. But here we are not
 * talking any user store and values has been hard corded in the source.
 */
public class RBACSubjectAttributeFinderModule extends AttributeFinderModule {

	private URI defaultSubjectId;
	private static Log log = LogFactory
			.getLog(FileBasedPolicyFinderModule.class);

	public RBACSubjectAttributeFinderModule() {

		try {
			defaultSubjectId = new URI(
					"urn:oasis:names:tc:xacml:1.0:subject:subject-id");
		} catch (URISyntaxException e) {
			// ignore
		}
	}

	@Override
	public Set<String> getSupportedCategories() {
		Set<String> categories = new HashSet<String>();
		categories
				.add("urn:oasis:names:tc:xacml:1.0:subject-category:access-subject");
		// categories.add("urn:oasis:names:tc:xacml:3.0:attribute-category:resource");
		return categories;
	}

	@Override
	public Set getSupportedIds() {
		Set<String> ids = new HashSet<String>();
		ids.add("role");
		return ids;
	}

	@Override
	public EvaluationResult findAttribute(URI attributeType, URI attributeId,
			String issuer, URI category, EvaluationCtx context) {

		String userName = "";
		EvaluationResult result = context.getAttribute(attributeType,
				defaultSubjectId, issuer, category);

		if (result != null && result.getAttributeValue() != null
				&& result.getAttributeValue().isBag()) {
			BagAttribute bagAttribute = (BagAttribute) result
					.getAttributeValue();
			if (bagAttribute.size() > 0) {
				userName = ((AttributeValue) bagAttribute.iterator().next())
						.encode();
			} else {
				log.debug("subject not found");
			}
		}

		AttributeValue AttResult = findAttributes(userName, attributeId,
				attributeType);

		return new EvaluationResult(AttResult);
	}

	@Override
	public boolean isDesignatorSupported() {
		return true;
	}

	private AttributeValue findAttributes(String username, URI attribute,
			URI attributeType) {
		
		XmlDataHandler data = new XmlDataHandler("./sample/rbac/resources/data.xml");
		ArrayList<AttributeQuery> query = new ArrayList<AttributeQuery>();
		query.add(new AttributeQuery("id",username,StringAttribute.identifier));
		return data.getBagAttribute("user", query, attribute.getPath(), attributeType.toString());
	}
}
